#
#   Game.py
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; version 2 of the License.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   Copyright
#   Author: Nicholas F. Hoover
#   Contributors: Salvatore S. Gionfriddo
#   Created: 2007.07.03
#   Last Modified: 2007.07.10
#

import pygame
import Messages, Spawner, EventHandler
from hud import Background, HUD
from GameObjectManager import GameObjectManager
from Level import Level
from Levels import Levels


class Game(object):

    POINTS_PER_KILL = 500
    POINTS_PER_TICK = 1

    FPS = 30
    
    def __init__(self, screen, rManager):
        self.screen = screen
        self.background = Background(self.screen, (0,0), self.screen.get_size())
        
        
        self.gameObjectManager = GameObjectManager()
        self.gameObjectManager.linkAnimations(rManager, self.FPS)
        self.gameObjectManager.linkSounds(rManager)
        self.hud = HUD(self.screen)
        self.clock = pygame.time.Clock()
        self.eventHandler = EventHandler.GameEventHandler(self)

        self.musicOn = False
        self.initLevels()
        self.reset()

        
    def initLevels(self):
        statTrackers = {
                        'Kills':self.getKills,
                        'TotalKills':self.getTotalKills,
                        'Eaten': self.gameObjectManager.evilGreg.getKidsEaten,
                        'KillsByPunch': self.gameObjectManager.evilGreg.getKillsByPunch,
                        'KillsByKick': self.gameObjectManager.evilGreg.getKillsByKick,
                        'KillsByFlame': self.gameObjectManager.evilGreg.getKillsByFlame
                        }
        spawnFunctions = {
                    'Kid': self.gameObjectManager.addKid,
                    'FastKid': self.gameObjectManager.addFastKid,
                    'Pizza': self.gameObjectManager.addPizza,
                    'Drugs': self.gameObjectManager.addDrugs,
                    'Indian': self.gameObjectManager.addIndian,
                    }
        levels = Levels(statTrackers, spawnFunctions)
        self.levels = levels.getLevels()
        self.currentLevel = -1 # so we can call nextLevel to go to the 0th level

        
    def nextLevel(self):
        if self.currentLevel + 1 < len(self.levels):
            self.currentLevel += 1
            self.gameObjectManager.setSpawners(self.levels[self.currentLevel].spawners)
            #scoring
            self.total_score += self.getScore()
            self.totalKills += self.getKills()
            if self.levels[self.currentLevel].clearAtEnd:
                self.gameObjectManager.reset()
            if self.levels[self.currentLevel].resetStatsAtEnd:
                self.gameObjectManager.evilGreg.resetKills() #HACK
            self.timeScore = 0
            self.tintScreen()
            Messages.printLevel(self.screen, self.currentLevel, self.levels[self.currentLevel].description)
            self.pauseIt(False)

    def isLevelComplete(self):
        return self.levels[self.currentLevel].isLevelComplete()
    
    def mainLoop(self):
 
        self.nextLevel()
        while self.gameObjectManager.evilGreg.isAlive():
            if self.pause:
                self.pauseIt()
            self.clock.tick(self.FPS)
            self.eventHandler.doEvents(pygame.event.get())
            self.background.draw()
            self.gameObjectManager.update(self.screen)
            
            if self.isLevelComplete():
                self.nextLevel()
            (health, hunger, heartBurn, self.kills)  = self.gameObjectManager.evilGreg.getStats()
            self.hud.update(self.totalKills + self.kills, self.kills, health, hunger, heartBurn,
                self.levels[self.currentLevel].getRemaining(),
                self.levels[self.currentLevel].goalType,
                self.clock.get_fps())
            self.hud.draw()
            
            self.timeScore += 1
            pygame.display.flip()

        #This is a little bit #HACK
        self.background.draw()
        self.gameObjectManager.killEG(self.screen)
        self.hud.draw()
        pygame.display.flip()
            

    def getKills(self):
        return self.kills

    def getTotalKills(self):
        return self.totalKills + self.kills
    
    def reset(self):
        self.gameObjectManager.reset()
        self.totalKills = 0
        self.kills = 0
        self.timeScore = 0
        self.total_score = 0
        self.done = False
        self.pause = False
        self.currentLevel = -1
        

        
    def pauseIt(self, doTint = True):
        if doTint:
            self.tintScreen()
        Messages.printPaused(self.screen)
        pygame.display.flip()
        musicPlaying = self.musicOn
        if musicPlaying:
            pygame.mixer.music.pause()
            
        EventHandler.waitForKeyOrQuit(EventHandler.ENTER_KEY)
        self.pause = False
        self.gameObjectManager.evilGreg.clearNextAction()
            
        if musicPlaying:
            pygame.mixer.music.unpause()


    def getScore(self):
        return (self.timeScore * self.POINTS_PER_TICK) + (self.getKills() * self.POINTS_PER_KILL) + self.total_score


    def toggleMusic(self):
        self.musicOn = not self.musicOn
        if self.musicOn:
            pygame.mixer.music.unpause()
        else:
            pygame.mixer.music.pause()



    def startMusic(self):
        self.musicOn = True
        pygame.mixer.music.play(-1)

    def tintScreen(self):
        tint = pygame.Surface(self.screen.get_size())
        tint.fill((0,0,0))
        tint.set_alpha(40)
        self.screen.blit(tint,(0,0))
        
